import { create } from 'zustand';
import { globalPlayer } from 'python-player';
import { getBestExportMethod, supportsDownload, supportsClipboardAPI } from '../utils';
import globalEventManager, { PYTHON_EVENTS, PROJECT_EVENTS } from '../utils/eventManager';
import projectManager from '../utils/projectManager';
import editorManager from '../utils/editorManager';
import { Project } from '../types/Project';
import { EditorState } from '../types/EditorState';
import useSidebarStore from './sidebarStore';
import JSZip from 'jszip';

// Result 类型定义
const createResult = {
  success: (data = null) => ({ success: true, data, error: null, message: null }),
  error: (error, message) => ({ success: false, data: null, error, message })
};

// 全局项目初始化锁
let projectInitializationPromise = null;

const useProjectStore = create((set, get) => ({
  // 项目状态 - 统一从 Project 获取
  currentProject: new Project(),
  editorState: new EditorState(), // 编辑器状态管理
  
  // 初始化事件订阅
  initializeEventSubscriptions: async () => {
    // 订阅Python状态变化事件 - 更新到 Project
    const unsubscribeStatus = globalEventManager.on(PYTHON_EVENTS.STATUS_CHANGE, (status) => {
      const { currentProject } = get();
      if (currentProject) {
        currentProject.isRunning = status === 'running';
        set({ currentProject });
      }
    });
    
    // 返回取消订阅函数
    return () => {
      unsubscribeStatus();
    };
  },

  // 初始化项目（单独的方法）
  initializeProject: async () => {
    // 使用全局锁防止重复初始化
    if (projectInitializationPromise) {
      return await projectInitializationPromise;
    }
    
    projectInitializationPromise = (async () => {
      try {
        const { editorState } = get();
        
        // 检查是否已经有当前项目，避免重复创建
        let currentProject = get().currentProject;
        if (!currentProject || !currentProject.fs) {
          // 只有在没有当前项目或文件系统未设置时才创建新项目
          currentProject = await projectManager.createNewProject();
        }
      
        // 设置编辑器状态的文件系统引用
        editorState.setFileSystem(globalPlayer.fs);
        
        // 从项目配置中获取激活的文件ID
        const activeFileId = currentProject.activeFileId;
        if (activeFileId) {
          const activeFile = globalPlayer.fs.getItem(activeFileId);
          if (activeFile) {
            // 设置 EditorState 的激活文件（不加载内容到编辑器）
            editorState.setCurrentFile(activeFileId);
            
        // 同步设置 sidebar 的选中文件
        const { setSelectedFile, expandFolder } = useSidebarStore.getState();
        setSelectedFile(activeFileId);
        
        // 默认展开所有文件夹
        const allFiles = currentProject.getAllFiles();
        allFiles.forEach(file => {
          if (file.type === 'directory') {
            expandFolder(file.id);
          }
        });
          } else {
            console.warn(`项目配置警告：activeFileId ${activeFileId} 对应的文件不存在，将不设置默认激活文件`);
          }
        } else {
          console.info('项目没有设置默认激活文件，用户需要手动选择文件');
        }
        
        set({ currentProject, editorState });
        
        if (!currentProject.fs) {
          console.error('项目初始化失败：文件系统未正确设置');
        } else {
          // 触发项目初始化完成事件
          globalEventManager.emit(PROJECT_EVENTS.INITIALIZED, {
            project: currentProject,
            editorState
          });
        }
      } catch (error) {
        console.error('项目初始化失败:', error);
        throw error;
      }
    })();
    
    return await projectInitializationPromise;
  },

  // ========== 便捷的 getter 方法，从 Project 获取数据 ==========
  
  // 获取运行状态
  get isRunning() {
    return get().currentProject?.isRunning || false;
  },

  // 获取项目信息
  getProjectInfo: () => {
    const { currentProject } = get();
    return {
      id: currentProject?.id,
      name: currentProject?.name,
      description: currentProject?.description,
      version: currentProject?.version,
      createdAt: currentProject?.createdAt,
      lastModified: currentProject?.lastModified,
      isRunning: currentProject?.isRunning || false,
      isDirty: currentProject?.isDirty || false
    };
  },

  // 获取当前文件信息
  getCurrentFileInfo: () => {
    const { editorState } = get();
    return editorState.getCurrentFile();
  },

  // 获取当前文件代码
  getCurrentFileCode: async () => {
    const { editorState } = get();
    const currentFile = editorState.getCurrentFile();
    if (!currentFile) {
      return null;
    }
    try {
      const content = await currentFile.getContent('text') || '';
      return content;
    } catch (error) {
      console.error('获取文件内容失败:', error);
      return '';
    }
  },

  // 获取当前打开的文件ID
  getCurrentOpenedFileId: () => {
    const { editorState } = get();
    return editorState.getCurrentFileId();
  },

  // 获取所有打开的文件
  getOpenedFiles: () => {
    const { editorState } = get();
    return editorState.getOpenedFiles();
  },

  // 获取所有文件列表
  getAllFiles: () => {
    const { currentProject } = get();
    return currentProject?.getAllFiles() || [];
  },

  // 获取 Python 文件列表
  getPythonFiles: () => {
    const { currentProject } = get();
    return currentProject?.getPythonFiles() || [];
  },

  // 获取执行历史
  getExecutionHistory: () => {
    const { currentProject } = get();
    return currentProject?.executionHistory || [];
  },

  // ========== 文件状态管理方法 ==========
  
  // 运行当前文件
  runCurrentFile: async () => {
    try {
      const { currentProject } = get();
      
      if (currentProject?.isRunning) {
        await projectManager.stopRunning();
        return createResult.success();
      } else {
        if (!currentProject) {
          return createResult.error('NO_PROJECT', '没有当前项目');
        }
        
        const currentFile = get().getCurrentFileInfo();
        if (!currentFile) {
          return createResult.error('NO_FILE_OPENED', '没有可运行的文件，请先创建或打开一个Python文件');
        }
        
        // 设置运行状态
        currentProject.isRunning = true;
        set({ currentProject });
        
        // 运行文件
        await globalPlayer.run(currentFile.id);
        
        // 记录执行历史
        currentProject.addExecutionHistory({
          code: currentFile.content,
          fileId: currentFile.id,
          fileName: currentFile.name,
          status: 'executed'
        });
        
        // 更新项目状态
        set({ currentProject: projectManager.getCurrentProject() });
        
        return createResult.success({ 
          fileName: currentFile.name, 
          fileContent: currentFile.content 
        });
      }
    } catch (error) {
      // 运行出错，重置状态
      const { currentProject } = get();
      if (currentProject) {
        currentProject.isRunning = false;
        set({ currentProject });
      }
      
      // 捕获运行时错误
      if (error.isSkulptError) {
        return createResult.error('RUNTIME_ERROR', '代码执行出错，请检查代码语法和逻辑');
      } else if (error.isFileTypeError) {
        return createResult.error('FILE_TYPE_ERROR', error.message);
      } else {
        return createResult.error('UNKNOWN_ERROR', `运行出错: ${error.message}`);
      }
    }
  },

  // 更新文件内容（用于编辑器自动保存）
  updateCurrentFileContent: async (code) => {
    try {
      const { currentProject, editorState } = get();
      
      if (!currentProject || !editorState.currentFileId) {
        return createResult.error('NO_FILE_OPENED', '没有当前打开的文件');
      }
      
      // 直接操作文件系统
      await globalPlayer.setCode(code, editorState.currentFileId);
      
      // 标记项目为已修改
      currentProject.markDirty();
      
      return createResult.success();
    } catch (error) {
      return createResult.error('SAVE_ERROR', `保存文件失败: ${error.message}`);
    }
  },


  
  // 停止代码执行
  stopCode: async () => {
    const { currentProject } = get();
    if (currentProject?.isRunning) {
      await projectManager.stopRunning();
      
      // 更新项目状态
      currentProject.isRunning = false;
      set({ currentProject });
    }
  },
  
  exportProject: async (options = {}) => {
    const { currentProject } = get();
    const { onShowDialog, onCopySuccess, onDownloadSuccess, onError } = options;
    
    try {
      if (!currentProject) {
        throw new Error('没有当前项目');
      }
      
      // 先保存项目
      await projectManager.saveProject();
      
      const files = currentProject.getAllFiles();
      console.log('检测到文件数量:', files.length, files);
      
      if (files.length > 1) {
        // 多文件导出为zip
        const zipFileName = `${currentProject.name}.zip`;
        const fileData = files.map(file => ({
          id: file.id,
          name: file.name,
          parentId: file.parentId,
          type: file.type,
          content: file.content
        }));
        return await get().downloadZipFile(fileData, zipFileName, { onDownloadSuccess, onError });
      } else if (files.length === 1) {
        // 单文件导出
        const singleFile = files[0];
        const exportMethod = getBestExportMethod();
        
        switch (exportMethod) {
          case 'download':
            return await get().downloadFile(singleFile.content, singleFile.name, { onDownloadSuccess, onError });
          
          case 'copy':
            return await get().copyToClipboard(singleFile.content, { onCopySuccess, onError });
          
          case 'dialog':
          default:
            if (onShowDialog) {
              onShowDialog(singleFile.content, singleFile.name);
              return { success: true, method: 'dialog' };
            } else {
              return await get().copyToClipboard(singleFile.content, { onCopySuccess, onError });
            }
        }
      }
      
      // 如果没有文件，返回错误
      throw new Error('没有找到可导出的文件');
    } catch (error) {
      console.error('导出失败:', error);
      if (onError) {
        onError(error);
      }
      return { success: false, error: error.message };
    }
  },

  // 直接下载文件
  downloadFile: async (code, fileName, options = {}) => {
    const { onDownloadSuccess, onError } = options;
    
    try {
      if (!supportsDownload()) {
        throw new Error('当前环境不支持文件下载');
      }

      const blob = new Blob([code], { type: 'text/plain;charset=utf-8' });
      const url = URL.createObjectURL(blob);
      
      const link = document.createElement('a');
      link.href = url;
      link.download = fileName;
      link.style.display = 'none';
      
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      
      URL.revokeObjectURL(url);
      
      if (onDownloadSuccess) {
        onDownloadSuccess(fileName);
      }
      
      return { success: true, method: 'download', fileName };
    } catch (error) {
      console.error('文件下载失败:', error);
      if (onError) {
        onError(error);
      }
      throw error;
    }
  },

  // 下载zip文件
  downloadZipFile: async (files, zipFileName, options = {}) => {
    const { onDownloadSuccess, onError } = options;
    
    try {
      if (!supportsDownload()) {
        throw new Error('当前环境不支持文件下载');
      }

      const zip = new JSZip();
      
      // 构建文件路径的函数
      const buildFilePath = (file, allFiles) => {
        if (file.type === 'directory') {
          return null; // 跳过文件夹
        }
        
        const pathParts = [file.name];
        let currentParentId = file.parentId;
        
        // 向上遍历父级目录，构建完整路径
        while (currentParentId && currentParentId !== 'root') {
          const parent = allFiles.find(f => f.id === currentParentId);
          if (parent) {
            pathParts.unshift(parent.name);
            currentParentId = parent.parentId;
          } else {
            break;
          }
        }
        
        return pathParts.join('/');
      };
      
      // 获取所有文件来构建路径
      const { currentProject } = get();
      const allFiles = currentProject.getAllFiles();
      
      // 添加所有文件到zip，保持目录结构
      files.forEach(file => {
        const filePath = buildFilePath(file, allFiles);
        if (filePath) {
          zip.file(filePath, file.content);
        }
      });
      
      // 生成zip文件
      const zipBlob = await zip.generateAsync({ type: 'blob' });
      const url = URL.createObjectURL(zipBlob);
      
      const link = document.createElement('a');
      link.href = url;
      link.download = zipFileName;
      link.style.display = 'none';
      
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      
      URL.revokeObjectURL(url);
      
      if (onDownloadSuccess) {
        onDownloadSuccess(zipFileName);
      }
      
      return { success: true, method: 'download', fileName: zipFileName, filesCount: files.length };
    } catch (error) {
      console.error('Zip文件下载失败:', error);
      if (onError) {
        onError(error);
      }
      throw error;
    }
  },

  // 复制到剪贴板
  copyToClipboard: async (code, options = {}) => {
    const { onCopySuccess, onError } = options;
    
    try {
      if (supportsClipboardAPI()) {
        // 使用现代剪贴板API
        await navigator.clipboard.writeText(code);
      } else {
        // 回退到传统方式
        const textArea = document.createElement('textarea');
        textArea.value = code;
        textArea.style.position = 'fixed';
        textArea.style.opacity = '0';
        textArea.style.pointerEvents = 'none';
        
        document.body.appendChild(textArea);
        textArea.select();
        textArea.setSelectionRange(0, 99999); // 移动端兼容
        
        const successful = document.execCommand('copy');
        document.body.removeChild(textArea);
        
        if (!successful) {
          throw new Error('复制命令执行失败');
        }
      }
      
      if (onCopySuccess) {
        onCopySuccess();
      }
      
      return { success: true, method: 'copy' };
    } catch (error) {
      console.error('复制到剪贴板失败:', error);
      if (onError) {
        onError(error);
      }
      throw error;
    }
  },
  
  // 导入项目
  importProject: () => {
    return new Promise((resolve, reject) => {
      const input = document.createElement('input');
      input.type = 'file';
      input.accept = '.py,.txt,.json';
      input.style.display = 'none';
      
      input.onchange = async (event) => {
        const file = event.target.files?.[0];
        if (!file) {
          reject(new Error('未选择文件'));
          return;
        }
        
        const reader = new FileReader();
        reader.onload = async (e) => {
          const content = e.target?.result;
          if (typeof content === 'string') {
            try {
              // 导入项目
              const project = await projectManager.importProject(content);
              set({ currentProject: project });
              resolve(content);
            } catch (error) {
              reject(new Error(`项目导入失败: ${error.message}`));
            }
          } else {
            reject(new Error('文件读取失败'));
          }
        };
        reader.onerror = () => reject(new Error('文件读取错误'));
        reader.readAsText(file, 'utf-8');
      };
      
      document.body.appendChild(input);
      input.click();
      document.body.removeChild(input);
    });
  },
  
  // 更新项目信息
  updateProjectInfo: (info) => {
    const { currentProject } = get();
    if (currentProject) {
      currentProject.updateInfo(info);
      set({ currentProject: projectManager.getCurrentProject() });
    }
  },
  
  // 清空执行历史
  clearHistory: () => {
    const { currentProject } = get();
    if (currentProject) {
      currentProject.clearExecutionHistory();
      set({ currentProject: projectManager.getCurrentProject() });
    }
  },
  
  // 获取最近执行的代码
  getLastExecutedCode: () => {
    const { currentProject } = get();
    return currentProject ? currentProject.getLastExecutedCode() : null;
  },

  // ========== 项目操作方法 ==========
  
  // 创建新作品
  createNewProject: async (options = {}) => {
    try {
      // 创建新项目（会重新初始化文件系统）
      const newProject = await projectManager.createNewProject(options);
      
      // 重新创建编辑器状态
      const newEditorState = new EditorState();
      newEditorState.setFileSystem(globalPlayer.fs);
      
      // 更新状态
      set({ 
        currentProject: newProject, 
        editorState: newEditorState 
      });
      
      console.log('新作品创建完成:', newProject.name);
      return createResult.success(newProject);
    } catch (error) {
      console.error('创建新作品失败:', error);
      return createResult.error('CREATE_ERROR', `创建新作品失败: ${error.message}`);
    }
  },

  // ========== 文件操作方法 ==========
  
  // 创建新文件
  createNewFile: async (name, content = '') => {
    const file = await projectManager.createFile(name, content);
    set({ currentProject: projectManager.getCurrentProject() });
    return file;
  },

  // 获取项目统计信息
  getProjectStats: () => {
    return projectManager.getProjectStats();
  },

  // 获取项目名称
  getProjectName: () => {
    const { currentProject } = get();
    return currentProject ? currentProject.name : '新的作品';
  },

  // ========== 编辑器状态管理方法 ==========
  
  openFile: (fileId) => {
    const { editorState } = get();
    const success = editorState.openFile(fileId);
    if (success) {
      set({ editorState });
    }
    return success;
  },

  closeFile: (fileId) => {
    const { editorState } = get();
    const success = editorState.closeFile(fileId);
    if (success) {
      set({ editorState });
    }
    return success;
  },

  setCurrentFile: async (fileId, loadToEditor = true) => {
    const { editorState } = get();
    
    // 如果有当前文件，立即保存编辑器内容（不使用防抖）
    if (editorState.currentFileId) {
      try {
        const currentContent = editorManager.getValue();
        if (currentContent !== null && currentContent !== undefined) {
          // 直接调用文件系统更新，避免重复的保存逻辑
          await globalPlayer.setCode(currentContent, editorState.currentFileId);
          // 标记项目为已修改
          const { currentProject } = get();
          if (currentProject) {
            currentProject.markDirty();
          }
        }
      } catch (error) {
        console.error('保存当前文件内容失败:', error);
      }
    }
    
    const success = editorState.setCurrentFile(fileId);
    if (success) {
      // 如果需要加载到编辑器，则异步加载
      if (loadToEditor) {
        await editorState.loadCurrentFileToEditor();
      }
      set({ editorState });
    }
    return success;
  },

  // 加载当前文件内容到编辑器
  loadCurrentFileToEditor: async () => {
    const { editorState } = get();
    return await editorState.loadCurrentFileToEditor();
  },

  isFileOpened: (fileId) => {
    const { editorState } = get();
    return editorState.isFileOpened(fileId);
  },

  isCurrentFile: (fileId) => {
    const { editorState } = get();
    return editorState.isCurrentFile(fileId);
  },

  // 刷新项目状态 - 从 projectManager 重新获取当前项目
  refreshProject: () => {
    const currentProject = projectManager.getCurrentProject();
    if (currentProject) {
      set({ currentProject });
    }
  },
}));

export default useProjectStore;
